#include "game.h"
#include "defined-system-function.h"


int grade = 0;
int nn = rand() % 7;

int speedTime = 0;
int standard;

Dia dia[7][4];
struct Face face;

int blockColor[2];
int runCount = 0;

const char * title[] = {
   ".-------------------------------------------------------------.",
   "|_|_|_|_|_|  _|_|_|_|  _|_|_|_|_|  _|_|_|    _|_|_|    _|_|_| |",
   "|    _|      _|            _|      _|    _|    _|    _|       |",
   "|    _|      _|_|_|        _|      _|_|_|      _|      _|_|   |",
   "|    _|      _|            _|      _|    _|    _|          _| |",
   "|    _|      _|_|_|_|      _|      _|    _|  _|_|_|  _|_|_|   |",
   "'-------------------------------------------------------------'",
};
int length = sizeof(title) / sizeof(title[0]);



void inter_face()
{ 
	setColor(15); 
	int i, j;
	for (j = 0; j<FACE_Y; j++)
	{
		for (i = 0; i<FACE_X + 10; i++)
		{
			if (i == 0 || i == FACE_X - 1 || i == FACE_X + 9)
			{
				face.data[j][i] = Wall;                                          
				gotoxy(j, 2 * i);
				printf("▓");
			}
			else if (j == FACE_Y - 1)
			{
				face.data[j][i] = Box;
			}
			else
			{
				face.data[j][i] = Kong;
			}
		}
	}
	

	gotoxy(FACE_Y - 1,1);
	for (i = 1; i < 2 * (FACE_X + 9); i++)
	{
		printf("▓");
	}

	

	gotoxy(FACE_Y - 26, 2 * FACE_X + 2);
	printf("next:");

	gotoxy(FACE_Y - 18, 2 * FACE_X + 2);
	printf("左移：←");
	
	gotoxy(FACE_Y - 16, 2 * FACE_X + 2);
	printf("右移：→");
	
	gotoxy(FACE_Y - 14, 2 * FACE_X + 2);
	printf("旋转：space");
	
	gotoxy(FACE_Y - 12, 2 * FACE_X + 2);
	printf("暂停: S");
	
	gotoxy(FACE_Y - 10, 2 * FACE_X + 2);
	printf("退出: ESC");
	
	gotoxy(FACE_Y - 8, 2 * FACE_X + 2);
	printf("重新开始:R");
	
	gotoxy(FACE_Y - 7, 2 * FACE_X + 1);
	printf("当前分数：%d", grade);

}



void init_dia()
{
	int i, j, k, z;
	int tmp[4][4];


	for (i = 0; i<3; i++)
	dia[0][0].space[1][i] = 1;
	dia[0][0].space[2][1] = 1;


	for (i = 1; i<4; i++)
	dia[1][0].space[i][1] = 1;
	dia[1][0].space[1][2] = 1;
	

	for (i = 1; i<4; i++)
	dia[2][0].space[i][2] = 1;
	dia[2][0].space[1][1] = 1;
	

	for (i = 0; i<2; i++)
	{

		dia[3][0].space[1][i] = 1;
		dia[3][0].space[2][i + 1] = 1;
	

		dia[4][0].space[1][i + 1] = 1;
		dia[4][0].space[2][i] = 1;
	

		dia[5][0].space[1][i + 1] = 1;
		dia[5][0].space[2][i + 1] = 1;
	}
	
	for (i = 0; i<4; i++)
		dia[6][0].space[i][2] = 1;
	
	for (i = 0; i<7; i++)
	{
		for (z = 0; z<3; z++)
		{
			for (j = 0; j<4; j++)
			{
				for (k = 0; k<4; k++)
				{
					tmp[j][k] = dia[i][z].space[j][k];
				}
			}


			for (j = 0; j<4; j++)
			{
				for (k = 0; k<4; k++)
				{
					dia[i][z + 1].space[j][k] = tmp[4 - k - 1][j];
				}
			}
		}
	}

}


void draw_dia(int base, int space_c, int x, int y,int color)
{
	setColor(color);
	int i, j;
	for (i = 0; i<4; i++)
	{
		for (j = 0; j<4; j++)
		{
			gotoxy(x + i, 2 * (y + j));
			if (dia[base][space_c].space[i][j] == 1)
				printf("■");
		}
	}
}


void draw_kong(int base, int space_c, int x, int y)
{
	int i, j;
	for (i = 0; i<4; i++)
	{
		for (j = 0; j<4; j++)
		{
			gotoxy(x + i, 2 * (y + j));
			if (dia[base][space_c].space[i][j] == 1)
				printf("  ");
		}
	}
}

int pd(int n, int space_c, int x, int y)
{
	int i, j;
	for (i = 0; i<4; i++)
	{
		for (j = 0; j<4; j++)
		{
			if (dia[n][space_c].space[i][j] == 0)
				continue;
			else if (face.data[x + i][y + j] == Wall || face.data[x + i][y + j] == Box)
				return 0;
		}
	}
	return 1;
}



int xc()
{
	int i, j, k, sum;
	for (i = FACE_Y - 2; i>4; i--)
	{
		sum = 0;
		for (j = 1; j<FACE_X - 1; j++)
		{
			sum += face.data[i][j];
		}
		if (sum == 0)
			break;



		if (sum == FACE_X - 2)
		{
			grade += 100;
			prinfGrade();
			for (j = 1; j<FACE_X - 1; j++)
			{
				face.data[i][j] = Kong;
				gotoxy(i, 2 * j);
				printf(" ");
			}



			for (j = i; j>1; j--)
			{
				for (k = 1; k<FACE_X - 1; k++)
				{
					sum += face.data[j][k];
					face.data[j][k] = face.data[j - 1][k];
					face.color[j][k] = face.color[j - 1][k];
					if (face.data[j][k] == Kong)
					{
						gotoxy(j, 2 * k);
						printf(" ");
					}
					else
					{
						setColor(face.color[j][k]);
						gotoxy(j, 2 * k);
						printf("■");
					}
				}
			}

		}
	}
	endGame(grade);
	return 0;
}


void prinfGrade()
{
	setColor(15);
	saveGrade(grade);
	printTopScore(grade);
	gotoxy(FACE_Y - 7, 2 * FACE_X + 1);
	printf("当前分数：%d", grade);
}


void endGame(int grade)
{
	setColor(15);
	for (int i = 1; i<FACE_X - 1; i++)
	{
		if (face.data[1][i] == Box)
		{
			char n;
			system("cls");
			gotoxy(FACE_Y / 2, 2 * (FACE_X / 3));
			printf("GAME OVER!\n");
			do
			{
				gotoxy(FACE_Y / 2 + 2, 2 * (FACE_X / 3));
				setColor(15);
				printf("是否重新开始游戏(y/n): ");
				scanf("%c", &n);
				gotoxy(FACE_Y / 2 + 4, 2 * (FACE_X / 3));
				if (n != 'n' && n != 'N' && n != 'y' && n != 'Y')
					printf("输入错误，请重新输入!");
				else
					break;
			} while (1);
			if (n == 'n' || n == 'N')
			{
				gotoxy(FACE_Y / 2 + 4, 2 * (FACE_X / 3));
				printf("按任意键退出游戏！");
				exit(0);
			}
			else if (n == 'y' || n == 'Y')
				main();
		}
	}
}


void start_game()
{
	int n, ch, x = 0, y = FACE_X / 2 - 2, i, j;
	int space_c = 0;
	draw_kong(nn, space_c, 4, FACE_X + 3);
	n = nn;
	nn = rand() % 7;
	if (!runCount)
	{
		blockColor[0] = rand() % 16;
	}
	blockColor[1] = rand() % 16;
	draw_dia(nn, space_c, 4, FACE_X + 3,blockColor[1]);
	printTopScore(grade);
	while (1)
	{
		draw_dia(n, space_c, x, y,blockColor[0]);
		if (speedTime == 0)
			speedTime = standard;
		while (--speedTime)
		{
			if (_kbhit() != 0)
				break;
		}
		if (speedTime == 0)
		{
			if (pd(n, space_c, x + 1, y) == 1)
			{
				draw_kong(n, space_c, x, y);
				x++;
			}
			else
			{
				for (i = 0; i<4; i++)
				{
					for (j = 0; j<4; j++)
					{
						if (dia[n][space_c].space[i][j] == 1)
						{
							face.data[x + i][y + j] = Box;
							face.color[x + i][y + j] = blockColor[0];
							xc();
						}
					}
				}
                blockColor[0] = blockColor[1];
                blockColor[1] = rand() % 16;
                runCount++;
				return;
			}
		}
		else
		{
			ch = _getch();
			switch (ch)
			{
			case LEFT:
				if (pd(n, space_c, x, y - 1) == 1)
				{
					draw_kong(n, space_c, x, y);
					y--;
				}
				break;
			case RIGHT:
				if (pd(n, space_c, x, y + 1) == 1)
				{
					draw_kong(n, space_c, x, y);
					y++;
				}
				break;
			case DOWN:
				if (pd(n, space_c, x + 1, y) == 1)
				{
					draw_kong(n, space_c, x, y);
					x++;
				}
				break;
			case SPACE:
				if (pd(n, (space_c + 1) % 4, x + 1, y) == 1)
				{
					draw_kong(n, space_c, x, y);
					space_c = (space_c + 1) % 4;
				}
				break;
			case ESC:
				system("cls"); 
				setColor(15);
				gotoxy(FACE_Y / 2, FACE_X);
				printf("---游戏结束!---\n\n");
				gotoxy(FACE_Y / 2 + 2, FACE_X);
				printf("---按任意键退出!---\n");
				_getch();
				exit(0);
				break;
			case  'R':
			case  'r':
				main();
				exit(0);
			case  'S':
			case  's':
				while (1)
				{
					if (_kbhit() != 0)
						break;
				}
				break;
			}
		}
	}
}


void StartScreen()
{
		setColor(4);
        for (int i = 0;i < length;i++)
        {
            for (int j = 0;j < 10;j++)
            {
                putchar(' ');
            }
            printf("%s\n", title[i]);
        }
        gotoxy(90, 5);
        printf("第一版本");
        gotoxy(12, 10);
        setColor(9);
        printf("[1--简单]	");
        printf("[2--中等]	");
        printf("[3--难]");

        while (1)
        {
            if (_kbhit())
            {
 a:             int key = _getch();
                if (key == '1')
                {
                    system("cls");
					standard = 15000;
                    new_startGame();
                    break;
                }
                else if (key == '2')
                {
                    system("cls");
					standard = 10000;
					new_startGame();
                }
                else if (key == '3')
                {
                    system("cls");
					standard = 5000;
                    new_startGame();
                    break;
                }
                else
                {
                    gotoxy(15,10);
                    printf("请输入1，2，3中的任意一个数");
					if (_kbhit())
					{
						goto a;
					}
                }
            }
       }
}

void new_startGame()
{
	inter_face();
	init_dia();
	while (1)
		start_game();
}